package pzc.io.folder;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FolderErgodicer {
	public static int ERGO_MODE_FULL = 1;
	public static int ERGO_MODE_FOLDER = 2;
	
	private int ergoMode = ERGO_MODE_FULL;
	
	private List<FileEventActionListener> fileListeners = new ArrayList<FileEventActionListener>(); 
	private List<FolderEventActionListener> folderListeners = new ArrayList<FolderEventActionListener>(); 
	
	private List<FFilter> filters = new ArrayList<FFilter>();
	
	public FolderErgodicer(){
	}
	public FolderErgodicer(int ergoMode){
		this.ergoMode = ergoMode;
	}
	
	public final void ergodic(File folder) throws Exception {
		if(!folder.exists()){
			return;
			//throw new Exception("[" + folder.getAbsolutePath() + "] not exists");
		}
		if(!folder.isDirectory()){
			throw new Exception("[" + folder.getAbsolutePath() + "] not a folder");
		}
		// folder.listFiles() return value is not null, length >= 0
		File[] files = folder.listFiles();
		if(files != null && files.length > 0){
			for(int i=0;i<files.length;i++){
				File subFile = files[i];
				
				boolean isPass = true;
				for(FFilter filter : filters){
					if(filter.isPass(subFile.getAbsolutePath()) == false){
						isPass = false;
					}
				}
				if(isPass == false){
					continue;
				}
				
				if(subFile.isDirectory()){
					for(FolderEventActionListener folderListener : folderListeners){
						// folder pre process
						folderListener.preProcess(subFile);
					}
					// recursive
					ergodic(subFile);
					for(FolderEventActionListener folderListener : folderListeners){
						// folder post process
						folderListener.postProcess(subFile);
					}
				}else{
					if(this.ergoMode == ERGO_MODE_FULL){
						for(FileEventActionListener fileListener : fileListeners){
							fileListener.process(subFile);
						}
					}
				}
			}
		}
	}
	
	public final void addFileEventActionListener(FileEventActionListener fileListener){
		this.fileListeners.add(fileListener);
	}
	public final void addFolderEventActionListener(FolderEventActionListener folderListener){
		this.folderListeners.add(folderListener);
	}
	public final void addFFilter(FFilter filter){
		this.filters.add(filter);
	}
}
